﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
using GeoFramework.Gps.IO;
using LetsDoIt.Controls;
using LetsDoIt.Interfaces;

namespace LetsDoIt.Forms
{
	public partial class GpsSelectForm : UserControl, INavigationForm
	{

		List<Device> listDevices = new List<Device>();

        #region ctor

        public GpsSelectForm(MainForm host, string identity)
		{
			HostForm = host;
			Identity = identity;
			InitializeComponent();
        }

        #endregion ctor


        #region Implementation of INavigationForm

        public MainForm HostForm { get; set; }
		public string Identity { get; set; }
        public bool IsActive { get; set; }

		public void NavigationEnter(object sender)
		{
			HostForm.mnuSelectGPS.Enabled = false;
			StartDetection();
		}

		public void NavigationLeave()
		{
		    EndDetection();
            Devices.CancelDetection();
			HostForm.mnuSelectGPS.Enabled = true;
		}

		#endregion

		

		#region detection

		void Devices_DeviceDetectionStarted(object sender, EventArgs e)
		{
			this.Invoke((ThreadStart)delegate
			{
				// Show that detection has been started
				Log("Device detection has started.");
			});
		}

		void Devices_DeviceDetected(object sender, DeviceEventArgs e)
		{
			this.Invoke((ThreadStart)delegate()
			{
				// Update the log to show the success
				Log(e.Device.Name + " is a GPS device.");
				//
				listDevices.Add(e.Device);
				GpsDeviceInfo.GpsType type = GpsDeviceInfo.GpsType.Internal;
				if (e.Device is BluetoothDevice)
					type = GpsDeviceInfo.GpsType.Bluetooth;
				if (e.Device is SerialDevice)
					type = GpsDeviceInfo.GpsType.Serial;
				if (e.Device is GpsIntermediateDriver)
					type = GpsDeviceInfo.GpsType.Internal;
				lstDevicesEx.AddItem(new GpsDeviceItem(new GpsDeviceInfo(e.Device.Name, type)));
			});
		}

		void Devices_DeviceDetectionAttemptFailed(object sender, DeviceDetectionExceptionEventArgs e)
		{
			this.Invoke((ThreadStart)delegate()
			{
				// Update the log with the message
				Log("Err: " + e.Device.Name + ": " + e.Exception.Message);
			});
		}

		void Devices_DeviceDetectionAttempted(object sender, DeviceEventArgs e)
		{
			this.Invoke((ThreadStart)delegate()
			{
				// Update the log
				Log("Testing " + e.Device.Name + "...");
			});
		}

		void Devices_DeviceDetectionCompleted(object sender, EventArgs e)
		{
			this.Invoke((ThreadStart)delegate()
			{
				// Change the cursor back to normal
				Cursor.Current = Cursors.Default;

				// Update the log to show that the search has completed
				Log("Device detection has completed.");

				EndDetection();				
                if (listDevices.Count>0)
				{
					btnSelectSelectedGPS.Enabled = true;
				}
			});
		}

		#endregion detection


		#region methods

        private void StartDetection()
        {
            listDevices.Clear();
            lstDevicesEx.Items.Clear();
            Devices.DeviceDetectionStarted += new EventHandler(Devices_DeviceDetectionStarted);
            Devices.DeviceDetectionCompleted += new EventHandler(Devices_DeviceDetectionCompleted);
            Devices.DeviceDetected += new EventHandler<DeviceEventArgs>(Devices_DeviceDetected);
            Devices.DeviceDetectionAttempted += new EventHandler<DeviceEventArgs>(Devices_DeviceDetectionAttempted);
            Devices.DeviceDetectionAttemptFailed += new EventHandler<DeviceDetectionExceptionEventArgs>(Devices_DeviceDetectionAttemptFailed);
            Devices.BeginDetection();
        }

        private void EndDetection()
        {
            Devices.DeviceDetectionStarted -= new EventHandler(Devices_DeviceDetectionStarted);
            Devices.DeviceDetectionCompleted -= new EventHandler(Devices_DeviceDetectionCompleted);
            Devices.DeviceDetected -= new EventHandler<DeviceEventArgs>(Devices_DeviceDetected);
            Devices.DeviceDetectionAttempted -= new EventHandler<DeviceEventArgs>(Devices_DeviceDetectionAttempted);
            Devices.DeviceDetectionAttemptFailed -= new EventHandler<DeviceDetectionExceptionEventArgs>(Devices_DeviceDetectionAttemptFailed);
        }

		private void Log(string message)
		{
			//txtLog.Text += message + "\r\n";
		}

		#endregion methods


        #region events

        private void btnBack_Click(object sender, EventArgs e)
		{
			HostForm.NavigateBack(this, string.Empty);
		}

		private void btnSelect_Click(object sender, EventArgs e)
		{
			//select
			if (lstDevicesEx.SelectedItems.Count >= 0)
			{
				GpsDeviceInfo gps = (lstDevicesEx.SelectedItems[0] as GpsDeviceItem).GpsDevice;
				if (gps != null)
				{
					HostForm.Settings.GpsDeviceName = gps.Name;
					SettingsFactory.SaveSettings(HostForm.Settings);
					HostForm.NavigateBack(this, string.Empty);
					HostForm.InitGpsConnection();
				}
			}
        }

        #endregion events

    }
}
